package com.ants.modules.ArticleManage.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.ants.common.annotation.AutoLog;
import com.ants.common.annotation.RateLimiter;
import com.ants.common.constant.CacheConstant;
import com.ants.common.constant.CommonConstant;
import com.ants.modules.ArticleManage.entity.ArticleContent;
import com.ants.modules.ArticleManage.service.ArticleContentService;
import com.ants.modules.utils.ElasticSearchUtils;
import com.ants.common.system.api.ISysBaseAPI;
import com.ants.common.system.query.QueryGenerator;
import com.ants.common.utils.ImageUtil;
import com.ants.modules.ArticleManage.dto.ArticleManageDto;
import com.ants.modules.ArticleManage.entity.ArticleLikeCollection;
import com.ants.modules.ArticleManage.entity.ArticleManage;
import com.ants.modules.ArticleManage.service.ArticleLikeCollectionService;
import com.ants.modules.ArticleManage.service.ArticleManageService;
import com.ants.common.system.result.Result;
import com.ants.modules.ArticleManage.vo.ArticleManageVo;
import com.ants.modules.ArticleManage.vo.ArticleTimeAxisVo;
import com.ants.modules.PushBaidu.entity.PushBaidu;
import com.ants.modules.PushBaidu.service.PushBaiduService;
import com.ants.modules.articleFavorites.entity.ArticleFavoritesSub;
import com.ants.modules.articleFavorites.service.ArticleFavoritesSubService;
import com.ants.modules.articleFollow.entity.ArticleFollow;
import com.ants.modules.articleFollow.service.ArticleFollowService;
import com.ants.modules.articleLable.entity.ArticleLable;
import com.ants.modules.articleLable.service.ArticleLableService;
import com.ants.modules.articleResource.service.ArticleResourceService;
import com.ants.modules.articleSort.entity.ArticleSort;
import com.ants.modules.articleSort.service.ArticleSortService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * TODO
 * Author Chen
 * Date   2021/9/7 18:44
 */

@Slf4j
@Api(tags = "文章管理")
@RestController
@RequestMapping("/article")
public class ArticleManageController {

    @Autowired
    ArticleManageService articleManageService;
    @Autowired
    ArticleContentService articleContentService;
    @Autowired
    PushBaiduService pushBaiduService;
    @Autowired
    ArticleSortService articleSortService;
    @Autowired
    ArticleLableService articleLableService;
    @Autowired
    ArticleLikeCollectionService articleLikeCollectionService;
    @Autowired
    ArticleFavoritesSubService articleFavoritesSubService;
    @Autowired
    ElasticSearchUtils elasticSearchUtils;
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    ElasticsearchClient restHighLevelClient;
    @Autowired
    ArticleFollowService articleFollowService;
    @Autowired
    ArticleResourceService articleResourceService;

    @AutoLog(value = "文章管理-列表")
    @ApiOperation(value = "文章管理-列表", notes = "文章管理-列表")
    @GetMapping("/list")
    public Result<?> queryPageList(ArticleManage articleManage,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) throws IOException {
        String username = StpUtil.getLoginIdAsString();
        String columu = req.getParameter("column");
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX);
        BoolQuery.Builder boolQuery = new BoolQuery.Builder();
        boolQuery.must(m -> m
                        .term(t -> t
                                .field("createBy").value(username)))
                .must(queryBuilder2 -> queryBuilder2
                        .term(rangeQueryBuilder -> rangeQueryBuilder
                                .field("delFlag").value(0))
                );

        if (StrUtil.isNotBlank(articleManage.getTitle())) {
            boolQuery.must(m -> m
                    .fuzzy(f -> f
                            .field("title")
                            .value(articleManage.getTitle())
                            .fuzziness("1")));
        }
        if (StrUtil.isNotBlank(articleManage.getPublishState())) {
            boolQuery.must(m -> m
                    .term(t -> t
                            .field("publishState").value(articleManage.getPublishState()))
            );
        }
        if (StrUtil.isNotBlank(articleManage.getArticleType())) {
            boolQuery.must(t -> t
                    .term(m -> m
                            .field("articleType").value(articleManage.getArticleType()))
            );
        }

        builder.query(queryBuilder -> queryBuilder
                        .bool(boolQueryBuilder -> boolQuery))
                .sort(sort -> sort
                        .field(f -> f
                                .field(columu)
                                .order(SortOrder.Desc)
                        )
                )
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content", "abstractText")
                        )
                )
                .from((pageNo - 1) * pageSize).size(pageSize);
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            result.add(source);
        }
        IPage<ArticleManageDto> page = new Page<>();
        page.setRecords(result);
        page.setTotal(search.hits().total().value());
        return Result.ok(page);
    }


    @AutoLog(value = "文章管理-全部文章")
    @ApiOperation(value = "文章管理-全部文章", notes = "文章管理-全部文章")
    @GetMapping("/listAll")
    public Result<?> listAll(ArticleManage articleManage,
                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                             @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                             HttpServletRequest req) throws IOException {
        String columu = req.getParameter("column");
        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(CacheConstant.ES_INDEX);
        BoolQuery.Builder boolQuery = new BoolQuery.Builder();
        boolQuery.must(m -> m
                .term(rangeQueryBuilder -> rangeQueryBuilder
                        .field("delFlag").value(0))
        );

        if (StrUtil.isNotBlank(articleManage.getTitle())) {
            boolQuery.must(m -> m
                    .fuzzy(f -> f
                            .field("title")
                            .value(articleManage.getTitle())
                            .fuzziness("1")));
        }
        if (StrUtil.isNotBlank(articleManage.getPublishState())) {
            boolQuery.must(m -> m
                    .term(t -> t
                            .field("publishState").value(articleManage.getPublishState()))
            );
        }
        if (StrUtil.isNotBlank(articleManage.getArticleType())) {
            boolQuery.must(t -> t
                    .term(m -> m
                            .field("articleType").value(articleManage.getArticleType()))
            );
        }

        builder.query(queryBuilder -> queryBuilder
                        .bool(boolQueryBuilder -> boolQuery))
                .sort(sort -> sort
                        .field(f -> f
                                .field(columu)
                                .order(SortOrder.Desc)
                        )
                )
                .source(source -> source
                        .filter(f -> f
                                .excludes("html", "content", "abstractText")
                        )
                )
                .from((pageNo - 1) * pageSize).size(pageSize);
        SearchResponse<ArticleManageDto> search = restHighLevelClient.search(builder.build(),
                ArticleManageDto.class);
        List<ArticleManageDto> result = new ArrayList<>();
        for (Hit<ArticleManageDto> hit : search.hits().hits()) {
            ArticleManageDto source = hit.source();
            result.add(source);
        }
        IPage<ArticleManageDto> page = new Page<>();
        page.setRecords(result);
        page.setTotal(search.hits().total().value());
        return Result.ok(page);
    }


    @AutoLog(value = "回收站-列表")
    @ApiOperation(value = "回收站-列表", notes = "回收站-列表")
    @GetMapping("/deleteList")
    public Result<?> deleteList(ArticleManage articleManage,
                                @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                HttpServletRequest req) {
        String username = StpUtil.getLoginIdAsString();
        articleManage.setCreateBy(username);
        articleManage.setDelFlag(1);
        QueryWrapper<ArticleManage> queryWrapper = QueryGenerator.initQueryWrapper(articleManage, req.getParameterMap());
        Page<ArticleManage> page = new Page<ArticleManage>(pageNo, pageSize);
        IPage<ArticleManage> pageList = articleManageService.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    /**
     * 添加
     *
     * @param articleManage
     * @return
     */
    @AutoLog(value = "文章管理-添加")
    @ApiOperation(value = "文章管理-添加", notes = "文章管理-添加")
    @PostMapping(value = "/add")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add(@RequestBody ArticleManage articleManage) {
        articleManage.setDelFlag(CommonConstant.DEL_FLAG_0);
        articleManage.setIsRecommend("0");
        if ("1".equals(articleManage.getPublishState())) {
            articleManage.setPublishTime(new DateTime());
        } else if ("2".equals(articleManage.getPublishState())) {
            String quartzPushDate = articleManage.getQuartzPushDate();
            String quartzPushTime = articleManage.getQuartzPushTime();
            if (StrUtil.isBlank(quartzPushDate) && StrUtil.isBlank(quartzPushTime)) {
                return Result.error("定时发布失败！");
            }
            DateTime dateTime = DateUtil.parseDateTime(quartzPushDate + " " + quartzPushTime + ":00");
            articleManage.setPublishTime(dateTime);
        }
        articleManageService.save(articleManage);
        ArticleContent articleContent = new ArticleContent();
        articleContent.setMainId(articleManage.getId());
        articleContent.setContent(articleManage.getContent());
        articleContent.setHtml(articleManage.getHtml());
        articleContentService.save(articleContent);

        List<String> imgSrcList = ImageUtil.getImgSrc(articleManage.getHtml());
        articleResourceService.saveArticleResource(imgSrcList, articleManage.getId());

        if ("1".equals(articleManage.getPublishState())) {
            //update-begin-author:chenshuang date:2022-08-05   取消新增文章时推送百度普通收录
            //pushPost("https://www.wxmin.cn/articleDetails/" + articleManage.getId());
            //update-end-author:chenshuang date:2022-08-05   取消新增文章时推送百度普通收录

            // 将数据加入 es
            ArticleManageDto map = articleManageService.getArticleToESById(articleManage.getId());
            elasticSearchUtils.addDocument(CacheConstant.ES_INDEX, articleManage.getId(), map);
        }

        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param articleManage
     * @return
     */
    @AutoLog(value = "文章管理-编辑")
    @ApiOperation(value = "文章管理-编辑", notes = "文章管理-编辑")
    @PutMapping(value = "/edit")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> edit(@RequestBody ArticleManage articleManage) {
        if (articleManage.getPublishTime() == null || articleManage.getPublishNowFlag()) {
            articleManage.setPublishTime(new DateTime());
        } else if ("2".equals(articleManage.getPublishState())) {
            String quartzPushDate = DateUtil.formatDate(DateUtil.parseDate(articleManage.getQuartzPushDate()));
            String quartzPushTime = articleManage.getQuartzPushTime();
            if (StrUtil.isBlank(quartzPushDate) && StrUtil.isBlank(quartzPushTime)) {
                return Result.error("定时发布失败！");
            }
            DateTime dateTime = DateUtil.parseDateTime(quartzPushDate + " " + quartzPushTime + ":00");
            articleManage.setPublishTime(dateTime);
        }
        // update-begin-author:chenshuang date:2022-08-05   修改推送百度普通收录状态为未收录
        articleManage.setIsIncluded("0");
        // update-begin-author:chenshuang date:2022-08-05   修改推送百度普通收录状态为未收录


        articleManageService.updateById(articleManage);

        LambdaQueryWrapper<ArticleContent> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleContent::getMainId, articleManage.getId());
        ArticleContent articleContent = new ArticleContent();
        articleContent.setContent(articleManage.getContent());
        articleContent.setHtml(articleManage.getHtml());
        articleContentService.update(articleContent, lqw);

        List<String> imgSrcList = ImageUtil.getImgSrc(articleManage.getHtml());
        articleResourceService.saveArticleResource(imgSrcList, articleManage.getId());

        if ("1".equals(articleManage.getPublishState()) && !articleManage.getPublishNowFlag()) {
            // update-begin-author:chenshuang date:2022-08-05   取消新增文章时推送百度普通收录
            //pushPost("https://www.wxmin.cn/articleDetails/" + articleManage.getId());
            // update-end-author:chenshuang date:2022-08-05   取消新增文章时推送百度普通收录

            // update-begin-author:chenshuang date:2022-08-05   只有修改发布状态=已发布的文章才会实时更新ES数据
            ArticleManageDto map = articleManageService.getArticleToESById(articleManage.getId());
            elasticSearchUtils.updateDocument(CacheConstant.ES_INDEX, articleManage.getId(), map);
            // update-end-author:chenshuang date:2022-08-05   只有修改发布状态=已发布的文章才会实时更新ES数据

        } else if ("1".equals(articleManage.getPublishState()) && articleManage.getPublishNowFlag()) {
            ArticleManageDto map = articleManageService.getArticleToESById(articleManage.getId());
            elasticSearchUtils.addDocument(CacheConstant.ES_INDEX, articleManage.getId(), map);
        }

        return Result.ok("编辑成功!");
    }

    /**
     * 恢复
     *
     * @param id
     * @return
     */
    @AutoLog(value = "文章管理-恢复")
    @ApiOperation(value = "文章管理-恢复", notes = "文章管理-恢复")
    @GetMapping(value = "/recovery")
    public Result<?> recovery(@RequestParam String id) {
        articleManageService.updateArticleDelFlag(id, 0);
        ArticleManageDto articleManageDto = articleManageService.getArticleToESById(id);
        articleManageDto.setDelFlag(0);
        // 更新 es 索引内容
        elasticSearchUtils.updateDocument(CacheConstant.ES_INDEX, id, articleManageDto);
        return Result.ok("恢复成功!");
    }

    /**
     * @param id
     * @return
     * @功能：删除
     */
    @AutoLog(value = "文章管理-删除")
    @ApiOperation(value = "文章管理-删除", notes = "文章管理-删除")
    @DeleteMapping("/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
//        boolean ok = articleManageService.removeById(id);
        ArticleManageDto articleManageDto = articleManageService.getArticleToESById(id);

        boolean ok = articleManageService.updateArticleDelFlag(id, 1);
        articleManageDto.setDelFlag(1);
        // 更新 es 索引内容
        elasticSearchUtils.updateDocument(CacheConstant.ES_INDEX, id, articleManageDto);
        if (ok) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
    }

    /**
     * @param id
     * @return
     * @功能：彻底删除
     */
    @AutoLog(value = "文章管理-彻底删除")
    @ApiOperation(value = "文章管理-彻底删除", notes = "文章管理-彻底删除")
    @DeleteMapping("/thoroughDelete")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> thoroughDelete(@RequestParam(name = "id", required = true) String id) {
        boolean ok = articleManageService.removeById(id);
        // 同时删除收藏与点赞信息
        LambdaQueryWrapper<ArticleLikeCollection> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleLikeCollection::getArticleId, id);
        articleLikeCollectionService.remove(lqw);
        LambdaQueryWrapper<ArticleFavoritesSub> lqw2 = new LambdaQueryWrapper<>();
        lqw2.eq(ArticleFavoritesSub::getArticleId, id);
        articleFavoritesSubService.remove(lqw2);

        LambdaQueryWrapper<ArticleContent> lqw3 = new LambdaQueryWrapper<>();
        lqw3.eq(ArticleContent::getMainId, id);
        articleContentService.remove(lqw3);

        // 删除 es 索引内容
        elasticSearchUtils.deleteDocument(CacheConstant.ES_INDEX, id);
        if (ok) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
    }

    /**
     * @param ids
     * @return
     * @功能：批量删除
     */
    @DeleteMapping("/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        boolean ok = articleManageService.removeByIds(Arrays.asList(ids.split(",")));
        if (ok) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
    }

    /**
     * @param id
     * @return
     * @功能：根据id查询
     */
    @AutoLog(value = "文章管理-查询指定文章")
    @ApiOperation(value = "文章管理-查询指定文章", notes = "文章管理-查询指定文章")
    @GetMapping("/getById")
    public Result<?> getById(@RequestParam(name = "id", required = true) String id) {
        ArticleManage articleManage = articleManageService.getById(id);

        LambdaQueryWrapper<ArticleContent> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleContent::getMainId, id);
        ArticleContent one = articleContentService.getOne(lqw);
        articleManage.setContent(one.getContent());
        articleManage.setHtml(one.getHtml());
        return Result.ok(articleManage);
    }


    @AutoLog(value = "文章管理-置顶文章")
    @ApiOperation(value = "文章管理-置顶文章", notes = "文章管理-置顶文章")
    @PostMapping("/isTop")
    public Result<?> isTop(@RequestBody ArticleManage articleManage) {
        if ("1".equals(articleManage.getIsRecommend())) {
            LambdaQueryWrapper<ArticleManage> lqw = new LambdaQueryWrapper<>();
            lqw.eq(ArticleManage::getIsRecommend, "1");
            long count = articleManageService.count(lqw);
            if (count >= 2) {
                return Result.error(200, "请注意，最多只能置顶 2 篇文章！");
            }
        }
        boolean b = articleManageService.updateById(articleManage);
        if (b) {
            return Result.ok("操作成功！");
        }
        return Result.error(200, "操作失败！");
    }


    public void pushPost(String url) {
        String PostUrl = "http://data.zz.baidu.com/urls?site=www.wxmin.cn&token=WaSUZJVLgyKxfZIU";
        PrintWriter out = null;
        BufferedReader in = null;
        PushBaidu pushBaidu = new PushBaidu();
        pushBaidu.setPushTime(new Date());
        pushBaidu.setParam(url);
        pushBaidu.setState("成功");
        try {
            //建立URL之间的连接
            URLConnection conn = new URL(PostUrl).openConnection();
            //设置通用的请求属性
            conn.setRequestProperty("User-Agent", "curl/7.12.1");
            conn.setRequestProperty("Host", "data.zz.baidu.com");
            conn.setRequestProperty("Content-Type", "text/plain");
            conn.setRequestProperty("Content-Length", "83");
            //发送POST请求必须设置如下两行
            conn.setDoInput(true);
            conn.setDoOutput(true);
            //获取conn对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            //发送请求参数
            String param = url;
            out.print(param.trim());
            //进行输出流的缓冲
            out.flush();
            //通过BufferedReader输入流来读取Url的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        } catch (Exception e) {
            pushBaidu.setState("失败");
            pushBaidu.setErrMsg(e.getMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        pushBaiduService.save(pushBaidu);
    }


    /******  首页统计功能  开始 *****/
    /**
     * @return
     * @功能：归档 根据id
     */
    @AutoLog(value = "文章管理-根据时间轴分类统计")
    @ApiOperation(value = "文章管理-根据时间轴分类统计", notes = "文章管理-根据时间轴分类统计")
    @GetMapping("/articleGroupByCreateTime")
    @RateLimiter
    public Result<?> articleGroupByCreateTime() {
        String username = StpUtil.getLoginIdAsString();
        List<Map<String, Object>> listMaps = articleManageService.articleGroupByCreateTime(username);
        listMaps.forEach(e -> {
            String createMonth = String.valueOf(e.get("createMonth"));
            List<ArticleManage> list = articleManageService.getArticleByTime(createMonth, username);
            e.put("data", list);
        });
        return Result.ok(listMaps);
    }

    /**
     * @return
     * @功能：查询文章 根据id
     */
    @AutoLog(value = "文章管理-根据时间查询")
    @ApiOperation(value = "文章管理-根据时间查询", notes = "文章管理-根据时间查询")
    @GetMapping("/getArticleByTime")
    public Result<?> getArticleByTime(@RequestParam String time) {
        String username = StpUtil.getLoginIdAsString();
        List<ArticleManage> list = articleManageService.getArticleByTime(time, username);
        IPage<ArticleManage> page = new Page<>();
        page.setRecords(list);
        return Result.ok(page);
    }


    @AutoLog(value = "文章管理-根据时间统计（图表格式）")
    @ApiOperation(value = "文章管理-根据时间统计（图表格式）", notes = "文章管理-根据时间统计（图表格式）")
    @GetMapping("/articleStatisticsLineChart")
    public Result<?> articleStatisticsLineChart(@RequestParam String month) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        DateTime beginOfMonth = new DateTime();
        DateTime endOfMonth = new DateTime();
        try {
            if (StrUtil.isNotBlank(month)) {
                date = sdf.parse(month + "-01");
                beginOfMonth = DateUtil.beginOfMonth(date);
                endOfMonth = DateUtil.endOfMonth(date);
            } else {
                date = sdf.parse(DateUtil.today());
                beginOfMonth = DateUtil.beginOfMonth(new Date());
                endOfMonth = DateUtil.endOfMonth(new Date());
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int actualMaximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= actualMaximum; i++) {
            String b = "0";
            if (i < 10) {
                sb.append(" UNION SELECT '" + 0 + i + "' `month`,0 articleNum,0 viewsNum,0 likesNum,0 collectNum");
            } else {
                sb.append(" UNION SELECT '" + i + "' `month`,0 articleNum,0 viewsNum,0 likesNum,0 collectNum");
            }
        }
        String startTime = DateUtil.formatDateTime(beginOfMonth);
        String endTime = DateUtil.formatDateTime(endOfMonth);
        String username = StpUtil.getLoginIdAsString();
        List<Map<String, Object>> mapList = articleManageService.articleStatisticsLineChart(username, startTime, endTime, sb.toString());
        return Result.ok(mapList);
    }

    @AutoLog(value = "文章管理-统计相关数据")
    @ApiOperation(value = "文章管理-统计相关数据", notes = "文章管理-统计相关数据")
    @GetMapping("/statisticsTopNum")
    public Result<?> statisticsTopNum() {
        String username = StpUtil.getLoginIdAsString();
        LambdaQueryWrapper<ArticleManage> articleManagelqw = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<ArticleLikeCollection> articleLikeCollectionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<ArticleSort> articleSortLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<ArticleLable> articleLableLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (StrUtil.isNotBlank(username)) {
            articleManagelqw.eq(ArticleManage::getCreateBy, username);
            articleLikeCollectionLambdaQueryWrapper.eq(ArticleLikeCollection::getCreateBy, username);
            articleSortLambdaQueryWrapper.eq(ArticleSort::getCreateBy, username);
            articleLableLambdaQueryWrapper.eq(ArticleLable::getCreateBy, username);
        }
        Map<String, Long> map = new HashMap<>();
        long articleCount = articleManageService.count(articleManagelqw);
        long likeCount = articleLikeCollectionService.count(articleLikeCollectionLambdaQueryWrapper);
        long sortCount = articleSortService.count(articleSortLambdaQueryWrapper);
        long lableCount = articleLableService.count(articleLableLambdaQueryWrapper);
        long viewcount = articleManageService.getViewNumSum(username);
        map.put("articleCount", articleCount);
        map.put("likeCount", likeCount);
        map.put("sortCount", sortCount);
        map.put("lableCount", lableCount);
        map.put("viewcount", viewcount);
        return Result.ok(map);
    }

    /**
     * @return
     * @功能：根据分类统计
     */
    @GetMapping("/getLableStatistics")
    public Result<?> getLableStatistics() {
        String username = StpUtil.getLoginIdAsString();
        List<ArticleManageVo> list = articleManageService.initArticleLable(username);
        return Result.ok(list);
    }

    /******  首页统计功能  结束 *****/

    @GetMapping("/getWxMyArticle")
    public Result<?> getWxMyArticle(@RequestParam(name = "offset", defaultValue = "0") Integer offset,
                                    @RequestParam String track,
                                    @RequestParam String token) {
        String username = (String) StpUtil.getLoginIdByToken(token);
        List<Map<String, Object>> list = null;
        if ("likes".equals(track)) {
            // 我的点赞
            list = articleManageService.getWxMyLikesArticle(username, offset);
        } else if ("favorites".equals(track)) {
            // 我的收藏y
            list = articleManageService.getWxMyCollectArticle(username, offset);
        } else if ("comments".equals(track)) {
            // 我的评论
        }
        list.forEach(e -> {
            e.put("publishTime", DateUtil.formatDate(DateUtil.parseDate(String.valueOf(e.get("publishTime")))));
//
            String articleSort = String.valueOf(e.get("article_sort"));
            List<ArticleSort> articleSorts = articleSortService.listByIds(Arrays.asList(articleSort.split(",")));
            e.put("tags", articleSorts);
        });


        return Result.ok(list);
    }


    /**
     * 点赞
     *
     * @param articleLikeCollection
     * @return
     */
    @PostMapping("/wxLike")
    @RateLimiter
    @Transactional(rollbackFor = Exception.class)
    public Result<?> wxLike(@RequestBody ArticleLikeCollection articleLikeCollection) {
        boolean isLike = true;
        // 判断是都存在，存在就是取消点赞
        String username = StpUtil.getLoginIdAsString();// 获取当前会话账号id, 并转化为`String`类型
        LambdaQueryWrapper<ArticleLikeCollection> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ArticleLikeCollection::getUsername, username)
                .eq(ArticleLikeCollection::getArticleId, articleLikeCollection.getArticleId());
        ArticleLikeCollection one = articleLikeCollectionService.getOne(lqw);
        ArticleManage byId = articleManageService.getById(articleLikeCollection.getArticleId());
        if (Objects.isNull(one)) {
            articleLikeCollection.setUsername(username);
            articleLikeCollectionService.save(articleLikeCollection);
            byId.setLikesNum(byId.getLikesNum() + 1);
            isLike = true;
        } else {
            isLike = false;
            articleLikeCollectionService.remove(lqw);
            byId.setLikesNum(byId.getLikesNum() - 1);
        }
        articleManageService.updateById(byId);
        // 更新es数据
        sysBaseAPI.executeJob("1519659919098253313");
        return Result.ok(isLike);

    }

    /**
     * @return
     * @功能：归档 个人中心呢-时间轴
     */
    @AutoLog(value = "个人中心-时间轴")
    @ApiOperation(value = "个人中心-时间轴", notes = "个人中心-时间轴")
    @GetMapping("/articleTimeAxis")
    @RateLimiter
    public Result<?> articleTimeAxis() {
        String username = StpUtil.getLoginIdAsString();
        List<ArticleManageDto> list = articleManageService.getArticleAllByUser(username);
        Map<String, List<ArticleManageDto>> result = list
                .stream()
                .collect(Collectors.groupingBy(entity -> DateUtil.format(entity.getPublishTime(), DatePattern.NORM_DATE_PATTERN)));
        List<ArticleTimeAxisVo> timeAxisVoList = new LinkedList<>();
        ArticleTimeAxisVo articleTimeAxisVo = null;
        for (Map.Entry<String, List<ArticleManageDto>> entry : result.entrySet()) {
            articleTimeAxisVo = new ArticleTimeAxisVo();
            articleTimeAxisVo.setKey(entry.getKey());
            articleTimeAxisVo.setValue(entry.getValue());
            timeAxisVoList.add(articleTimeAxisVo);
        }

        return Result.ok(timeAxisVoList);
    }

    /**
     * @return
     * @功能：归档 个人中心-时间轴
     */
    @AutoLog(value = "个人中心-数据看板-博客数据统计")
    @ApiOperation(value = "个人中心-数据看板-博客数据统计", notes = "个人中心-数据看板-博客数据统计")
    @GetMapping("/blogDataStatistics")
    @RateLimiter
    public Result<?> blogDataStatistics() {
        String username = StpUtil.getLoginIdAsString();
        // 文章数
        LambdaQueryWrapper<ArticleManage> articleManagelqw = new LambdaQueryWrapper<>();
        articleManagelqw.eq(ArticleManage::getCreateBy, username);
        articleManagelqw.eq(ArticleManage::getDelFlag, 0);
        long articleNum = articleManageService.count(articleManagelqw);
        // 粉丝数
        LambdaQueryWrapper<ArticleFollow> articleFollowlqw = new LambdaQueryWrapper<>();
        articleFollowlqw.eq(ArticleFollow::getUsername, username);
        long followNum = articleFollowService.count(articleFollowlqw);
        // 点赞数
        Integer likeNum = articleManageService.getArticleLikeNumByUserNmae(username);
        // 阅读量
        Integer viewNum = articleManageService.getViewNumSum(username);
        // 收藏数
        Integer collectNum = articleManageService.getArticleFavoritesNumByUserNmae(username);
        // 分类数
        LambdaQueryWrapper<ArticleSort> articleSortlqw = new LambdaQueryWrapper<>();
        articleSortlqw.eq(ArticleSort::getCreateBy, username);
        long sortNum = articleSortService.count(articleSortlqw);
        // 标签数
        LambdaQueryWrapper<ArticleLable> articleLablelqw = new LambdaQueryWrapper<>();
        articleLablelqw.eq(ArticleLable::getCreateBy, username);
        long lableNum = articleLableService.count(articleLablelqw);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("articleNum", articleNum);
        resultMap.put("followNum", followNum);
        resultMap.put("likeNum", likeNum);
        resultMap.put("viewNum", viewNum);
        resultMap.put("collectNum", collectNum);
        resultMap.put("sortNum", sortNum);
        resultMap.put("lableNum", lableNum);
        return Result.ok(resultMap);
    }

}
